import { Checkbox, Divider, Empty, List, Skeleton } from 'antd';
import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';

import InfiniteScroll from 'react-infinite-scroll-component';
import Checkboxtem, { ListItemProps } from './Checkboxtem';
import CrumbList from './CrumbList';

export type CheckboxItem = {
  uniquedKey: string;
  /** 类型 - 1: 全部人员; 2: 备案企业; 3: 人员类型  */
  tab: string;
  /** ID */
  id: string;
  /** 类型 - 1: 人员; 2: 备案企业; 3: 人员类型  */
  type: string;
  /** 人员姓名 | 企业名称 | 人员职位 */
  name: string;
  /** 电话 */
  phone?: string;
  /** 数量 */
  count: number;
  /** 头像 */
  avatar?: string;
  /** 是否选中 */
  checked?: boolean;
};

export type CheckboxListProps = {
  tab: string;
  mergedData?: CheckboxItem[];
  dataSource?: CheckboxItem[];
  defaultCrumbList?: CheckboxItem[];
  value?: string[];
  loading?: boolean;
  total?: number;
  onCheckboxItemChange?: (
    checkedIds: string[],
    checkedItems: CheckboxItem[],
    currentValue: string,
    isChecked: boolean,
  ) => void;
  onAllCheck?: (checkedIds: string[], checkedItems: CheckboxItem[], currentValue: string[], isChecked: boolean) => void;
  onNextClick?: (value: CheckboxItem) => void;
  onPreviousClick?: (value: CheckboxItem) => void;
  loadMoreData?: () => void;
};

const CheckboxList: FC<CheckboxListProps> = ({
  tab,
  mergedData = [],
  dataSource = [],
  defaultCrumbList = [],
  value = [],
  loading = false,
  total = 0,
  onCheckboxItemChange,
  onAllCheck,
  onNextClick,
  onPreviousClick,
  loadMoreData,
}) => {
  const [crumbList, setCrumbList] = useState<CheckboxItem[]>(defaultCrumbList);
  const dataSourceRef = useRef<CheckboxItem[]>(dataSource);

  const [listItemsContainerRef, setListItemsContainerRef] = useState<any>(null);

  useEffect(() => {
    setCrumbList(defaultCrumbList);
  }, [defaultCrumbList]);

  // 是否全选
  const isAllChecked = useMemo(() => {
    const updatedDataSource = dataSource.filter((item) => value.includes(item.id));

    return updatedDataSource.length > 0 && updatedDataSource.length === dataSource.length;
  }, [value, dataSource]);

  // 是否部分选中
  const isIndeterminate = useMemo(() => {
    const updatedDataSource = dataSource.filter((item) => value.includes(item.id));

    return updatedDataSource.length > 0 && updatedDataSource.length < dataSource.length;
  }, [value, dataSource]);

  useEffect(() => {
    dataSourceRef.current = dataSource.map((item) => {
      return {
        ...item,
        checked: value.includes(item.id),
      };
    });
  }, [dataSource, value]);

  const onlistItemsContainerRefChange = useCallback((node: any) => {
    if (node !== null) {
      setListItemsContainerRef(node);
    }
  }, []);

  /**
   * 复选框 - 选择事件
   *
   * @param e
   */
  const onCheckboxtemChange: ListItemProps['onChange'] = (e) => {
    const updatedDataList = dataSourceRef.current.map((item) => {
      if (e.target.value === item.id) {
        return {
          ...item,
          checked: e.target.checked,
        };
      } else {
        return item;
      }
    });

    dataSourceRef.current = updatedDataList;

    onCheckboxItemChange?.(
      updatedDataList.filter((item) => item.checked).map((v) => v.id) as string[],
      updatedDataList,
      e.target.value,
      e.target.checked,
    );
  };

  /**
   * 全选 - 选择事件
   *
   * @param e
   */
  const allCheckHandler = (e: any) => {
    if (e.target.checked) {
      const updatedDataList = dataSourceRef.current.map((item) => {
        return {
          ...item,
          checked: e.target.checked,
        };
      });

      dataSourceRef.current = updatedDataList;

      onAllCheck?.(
        updatedDataList.filter((item) => item.checked).map((v) => v.id) as string[],
        updatedDataList,
        [],
        true,
      );
    } else {
      onAllCheck?.([], [], dataSourceRef.current.map((v) => v.id) as string[], false);
    }
  };

  /**
   * 面包屑 - 点击事件
   *
   * @param value
   */
  const crumbClickHandler = (value: CheckboxItem) => {
    const currentIndex = crumbList.findIndex((item) => item.id === value.id);

    const filteredArray = crumbList.slice(0, currentIndex + 1);

    setCrumbList(filteredArray);

    onPreviousClick?.(value);
  };

  /**
   * 下一级 - 点击事件
   *
   * @param value
   */
  const nextClickHandler = (value: CheckboxItem) => {
    setCrumbList([...crumbList, value]);

    onNextClick?.(value);
  };

  const loadMore = () => {
    loadMoreData?.();
  };

  return (
    <>
      <div
        style={{
          height: '100%',
          display: 'flex',
          flexDirection: 'column',
        }}
      >
        {crumbList.length > 1 && <CrumbList crumbList={crumbList} onCrumbClick={crumbClickHandler} />}
        <Checkbox
          onChange={allCheckHandler}
          indeterminate={isIndeterminate}
          checked={isAllChecked}
          style={{ marginLeft: 5, marginTop: 8 }}
        >
          全选
        </Checkbox>

        <div
          ref={onlistItemsContainerRefChange}
          style={{
            flex: 'auto',
            overflowY: 'auto',
            overflowX: 'hidden',
            height: 300,
          }}
        >
          <Skeleton loading={loading} active paragraph={{ rows: 4, width: 296 }} title={false}>
            <Checkbox.Group value={value} style={{ width: '100%' }}>
              {!loading && dataSource!.length <= 0 ? (
                <div
                  style={{
                    display: 'flex',
                    height: 200,
                    width: '100%',
                    justifyContent: 'center',
                    alignItems: 'center',
                  }}
                >
                  <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
                </div>
              ) : (
                <InfiniteScroll
                  dataLength={dataSource.length}
                  next={loadMore}
                  hasMore={dataSource.length < total}
                  loader={<Skeleton avatar paragraph={{ rows: 0 }} active />}
                  endMessage={<Divider plain>没有更多了~</Divider>}
                  scrollableTarget={listItemsContainerRef}
                >
                  <List
                    dataSource={dataSource}
                    renderItem={(item) => {
                      return (
                        <Checkboxtem
                          key={item.uniquedKey}
                          onChange={onCheckboxtemChange}
                          tab={item.tab}
                          uniquedKey={item.uniquedKey}
                          id={item.id}
                          name={item.name}
                          count={item.count}
                          phone={item.phone}
                          type={item.type}
                          avatar={item.avatar}
                          checked={value.includes(item.id)}
                          onNextClick={nextClickHandler}
                        />
                      );
                    }}
                  />
                </InfiniteScroll>
              )}

              {/* {dataSource.map((item) => {
                return (
                  <Checkboxtem
                    key={item.uniquedKey}
                    onChange={onCheckboxtemChange}
                    tab={item.tab}
                    uniquedKey={item.uniquedKey}
                    id={item.id}
                    name={item.name}
                    count={item.count}
                    phone={item.phone}
                    type={item.type}
                    avatar={item.avatar}
                    checked={value.includes(item.id)}
                    onNextClick={nextClickHandler}
                  />
                );
              })} */}
            </Checkbox.Group>
          </Skeleton>
        </div>
      </div>
    </>
  );
};

export default CheckboxList;
